using MediatR;
using RBAC.Domain.WarehouseManagement;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Read.Api.Application.Command.ERP.WarehouseManagement;
using Dapper;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Linq;

namespace RBAC.Read.Api.Application.Handler.ERP.WarehouseManagement
{
    /// <summary>
    /// 仓库列表导出处理器（NPOI + Dapper）
    /// </summary>
    public class ExportWarehouseListCommandHandler : IRequestHandler<ExportWarehouseListCommands, APIResult<byte[]>>
    {
        private readonly IBaseRepository<WarehouseList> _warehouseListRep;

        public ExportWarehouseListCommandHandler(IBaseRepository<WarehouseList> warehouseListRep)
        {
            _warehouseListRep = warehouseListRep;
        }

        public async Task<APIResult<byte[]>> Handle(ExportWarehouseListCommands request, CancellationToken cancellationToken)
        {
            try
            {
                // 1) 组织查询条件（Dapper 参数化）
                var where = string.Empty;
                var param = new DynamicParameters();
                if (!string.IsNullOrWhiteSpace(request.WarehouseName))
                {
                    where = "WarehouseName LIKE @WarehouseName";
                    param.Add("@WarehouseName", $"%{request.WarehouseName}%");
                }

                // 2) 查询数据（不分页）
                var data = _warehouseListRep.GetAll(where, param);
                // 立即物化，避免外部连接/读取器在后续被释放导致的访问异常
                var list = data?.ToList() ?? new List<WarehouseList>();
                if (list.Count == 0)
                {
                    return new APIResult<byte[]>
                    {
                        Code = APIEnums.Fail,
                        Msg = "没有可导出的仓库数据",
                        Data = Array.Empty<byte>()
                    };
                }

                // 3) 生成 Excel（NPOI）
                // 不使用 using 包裹 wb，避免某些版本/环境下在 Write 期间过早释放内部资源
                var wb = new XSSFWorkbook();
                var sheet = wb.CreateSheet("仓库列表");

                var headers = new[]
                {
                    "仓库代码","仓库名称","仓库料品","入库类型","出库类型",
                    "货位启用","到货类型","仓库期间","截止日","开始时间",
                    "仓库状态","表单配置","仓管员","操作员","创建时间","创建人"
                };

                var headerRow = sheet.CreateRow(0);
                for (int i = 0; i < headers.Length; i++)
                {
                    headerRow.CreateCell(i).SetCellValue(headers[i]);
                }

                for (int r = 0; r < list.Count; r++)
                {
                    var w = list[r];
                    var row = sheet.CreateRow(r + 1);

                    row.CreateCell(0).SetCellValue(w.WarehouseCode ?? string.Empty);
                    row.CreateCell(1).SetCellValue(w.WarehouseName ?? string.Empty);
                    row.CreateCell(2).SetCellValue(w.WarehouseMaterials ?? string.Empty);
                    row.CreateCell(3).SetCellValue(w.StorageType ?? string.Empty);
                    row.CreateCell(4).SetCellValue(w.OutboundType ?? string.Empty);
                    row.CreateCell(5).SetCellValue(w.GoodsPosition ? "启用" : "不启用");
                    row.CreateCell(6).SetCellValue(w.ArrivalType ?? string.Empty);
                    row.CreateCell(7).SetCellValue(w.WarehouseDue ? "固定日" : "自然月");
                    row.CreateCell(8).SetCellValue(w.DeadlineDay.ToString());
                    row.CreateCell(9).SetCellValue(w.StartTime.ToString("yyyy-MM-dd HH:mm:ss"));
                    row.CreateCell(10).SetCellValue(w.WarehouseStatus ? "启用" : "停用");
                    row.CreateCell(11).SetCellValue(w.FormConfiguration ?? string.Empty);
                    row.CreateCell(12).SetCellValue(w.WarehouseManager ?? string.Empty);
                    row.CreateCell(13).SetCellValue(w.Operator ?? string.Empty);
                    row.CreateCell(14).SetCellValue(w.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                    row.CreateCell(15).SetCellValue(w.CreateUser ?? string.Empty);
                }

                // 去掉自动列宽，避免个别环境下 NPOI 字体度量依赖导致异常
                // 如需列宽可改用固定宽度：sheet.SetColumnWidth(i, 20 * 256);

                using var ms = new MemoryStream();
                wb.Write(ms);
                ms.Flush();
                var bytes = ms.ToArray();

                if (bytes.Length == 0)
                {
                    return new APIResult<byte[]>
                    {
                        Code = APIEnums.Fail,
                        Msg = "生成的Excel文件为空",
                        Data = Array.Empty<byte>()
                    };
                }

                return new APIResult<byte[]>
                {
                    Code = APIEnums.Success,
                    Msg = $"成功导出{list.Count}条数据",
                    Data = bytes
                };
            }
            catch (Exception ex)
            {
                return new APIResult<byte[]>
                {
                    Code = APIEnums.Fail,
                    Msg = "导出失败：" + ex.ToString(),
                    Data = Array.Empty<byte>()
                };
            }
        }
    }
}
